home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gsiodev.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  9.6 KB  |  358 lines

  1. /* Copyright (C) 1993, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gsiodev.c,v 1.3.2.1 2000/10/25 19:16:09 alexcher Exp $ */
  20. /* IODevice implementation for Ghostscript */
  21. #include "errno_.h"
  22. #include "string_.h"
  23. #include "gx.h"
  24. #include "gserrors.h"
  25. #include "gp.h"
  26. #include "gscdefs.h"
  27. #include "gsparam.h"
  28. #include "gsstruct.h"
  29. #include "gxiodev.h"
  30.  
  31. /* Import the IODevice table from gconf.c. */
  32. extern_gx_io_device_table();
  33.  
  34. /* Define a table of local copies of the IODevices, */
  35. /* allocated at startup.  This just postpones the day of reckoning.... */
  36. private gx_io_device **io_device_table;
  37.  
  38. private_st_io_device();
  39. gs_private_st_ptr(st_io_device_ptr, gx_io_device *, "gx_io_device *",
  40.           iodev_ptr_enum_ptrs, iodev_ptr_reloc_ptrs);
  41. gs_private_st_element(st_io_device_ptr_element, gx_io_device *,
  42.       "gx_io_device *[]", iodev_ptr_elt_enum_ptrs, iodev_ptr_elt_reloc_ptrs,
  43.               st_io_device_ptr);
  44.  
  45. /* Define the OS (%os%) device. */
  46. iodev_proc_fopen(iodev_os_fopen);
  47. iodev_proc_fclose(iodev_os_fclose);
  48. private iodev_proc_delete_file(os_delete);
  49. private iodev_proc_rename_file(os_rename);
  50. private iodev_proc_file_status(os_status);
  51. private iodev_proc_enumerate_files(os_enumerate);
  52. private iodev_proc_get_params(os_get_params);
  53. const gx_io_device gs_iodev_os =
  54. {
  55.     "%os%", "FileSystem",
  56.     {iodev_no_init, iodev_no_open_device,
  57.      NULL /*iodev_os_open_file */ , iodev_os_fopen, iodev_os_fclose,
  58.      os_delete, os_rename, os_status,
  59.      os_enumerate, gp_enumerate_files_next, gp_enumerate_files_close,
  60.      os_get_params, iodev_no_put_params
  61.     }
  62. };
  63.  
  64. /* ------ Initialization ------ */
  65.  
  66. init_proc(gs_iodev_init);    /* check prototype */
  67. int
  68. gs_iodev_init(gs_memory_t * mem)
  69. {                /* Make writable copies of all IODevices. */
  70.     gx_io_device **table =
  71.     gs_alloc_struct_array(mem, gx_io_device_table_count,
  72.                   gx_io_device *, &st_io_device_ptr_element,
  73.                   "gs_iodev_init(table)");
  74.     int i, j;
  75.     int code = 0;
  76.  
  77.     if (table == 0)
  78.     return_error(gs_error_VMerror);
  79.     for (i = 0; i < gx_io_device_table_count; ++i) {
  80.     gx_io_device *iodev =
  81.         gs_alloc_struct(mem, gx_io_device, &st_io_device,
  82.                 "gs_iodev_init(iodev)");
  83.  
  84.     if (iodev == 0)
  85.         goto fail;
  86.     table[i] = iodev;
  87.     memcpy(table[i], gx_io_device_table[i], sizeof(gx_io_device));
  88.     }
  89.     io_device_table = table;
  90.     code = gs_register_struct_root(mem, NULL, (void **)&io_device_table,
  91.                    "io_device_table");
  92.     if (code < 0)
  93.     goto fail;
  94.     /* Run the one-time initialization of each IODevice. */
  95.     for (j = 0; j < gx_io_device_table_count; ++j)
  96.     if ((code = (table[j]->procs.init)(table[j], mem)) < 0)
  97.         goto f2;
  98.     return 0;
  99.  f2:
  100.     /****** CAN'T FIND THE ROOT ******/
  101.     /*gs_unregister_root(mem, root, "io_device_table");*/
  102.  fail:
  103.     for (; i >= 0; --i)
  104.     gs_free_object(mem, table[i - 1], "gs_iodev_init(iodev)");
  105.     gs_free_object(mem, table, "gs_iodev_init(table)");
  106.     io_device_table = 0;
  107.     return (code < 0 ? code : gs_note_error(gs_error_VMerror));
  108. }
  109.  
  110. /* ------ Default (unimplemented) IODevice procedures ------ */
  111.  
  112. int
  113. iodev_no_init(gx_io_device * iodev, gs_memory_t * mem)
  114. {
  115.     return 0;
  116. }
  117.  
  118. int
  119. iodev_no_open_device(gx_io_device * iodev, const char *access, stream ** ps,
  120.              gs_memory_t * mem)
  121. {
  122.     return_error(gs_error_invalidfileaccess);
  123. }
  124.  
  125. int
  126. iodev_no_open_file(gx_io_device * iodev, const char *fname, uint namelen,
  127.            const char *access, stream ** ps, gs_memory_t * mem)
  128. {
  129.     return_error(gs_error_invalidfileaccess);
  130. }
  131.  
  132. int
  133. iodev_no_fopen(gx_io_device * iodev, const char *fname, const char *access,
  134.            FILE ** pfile, char *rfname, uint rnamelen)
  135. {
  136.     return_error(gs_error_invalidfileaccess);
  137. }
  138.  
  139. int
  140. iodev_no_fclose(gx_io_device * iodev, FILE * file)
  141. {
  142.     return_error(gs_error_ioerror);
  143. }
  144.  
  145. int
  146. iodev_no_delete_file(gx_io_device * iodev, const char *fname)
  147. {
  148.     return_error(gs_error_invalidfileaccess);
  149. }
  150.  
  151. int
  152. iodev_no_rename_file(gx_io_device * iodev, const char *from, const char *to)
  153. {
  154.     return_error(gs_error_invalidfileaccess);
  155. }
  156.  
  157. int
  158. iodev_no_file_status(gx_io_device * iodev, const char *fname, struct stat *pstat)
  159. {
  160.     return_error(gs_error_undefinedfilename);
  161. }
  162.  
  163. file_enum *
  164. iodev_no_enumerate_files(gx_io_device * iodev, const char *pat, uint patlen,
  165.              gs_memory_t * memory)
  166. {
  167.     return NULL;
  168. }
  169.  
  170. int
  171. iodev_no_get_params(gx_io_device * iodev, gs_param_list * plist)
  172. {
  173.     return 0;
  174. }
  175.  
  176. int
  177. iodev_no_put_params(gx_io_device * iodev, gs_param_list * plist)
  178. {
  179.     return param_commit(plist);
  180. }
  181.  
  182. /* ------ %os% ------ */
  183.  
  184. /* The fopen routine is exported for %null. */
  185. int
  186. iodev_os_fopen(gx_io_device * iodev, const char *fname, const char *access,
  187.            FILE ** pfile, char *rfname, uint rnamelen)
  188. {
  189.     errno = 0;
  190.     *pfile = gp_fopen(fname, access);
  191.     if (*pfile == NULL)
  192.     return_error(gs_fopen_errno_to_code(errno));
  193.     if (rfname != NULL)
  194.     strcpy(rfname, fname);
  195.     return 0;
  196. }
  197.  
  198. /* The fclose routine is exported for %null. */
  199. int
  200. iodev_os_fclose(gx_io_device * iodev, FILE * file)
  201. {
  202.     fclose(file);
  203.     return 0;
  204. }
  205.  
  206. private int
  207. os_delete(gx_io_device * iodev, const char *fname)
  208. {
  209.     return (unlink(fname) == 0 ? 0 : gs_error_ioerror);
  210. }
  211.  
  212. private int
  213. os_rename(gx_io_device * iodev, const char *from, const char *to)
  214. {
  215.     return (rename(from, to) == 0 ? 0 : gs_error_ioerror);
  216. }
  217.  
  218. private int
  219. os_status(gx_io_device * iodev, const char *fname, struct stat *pstat)
  220. {                /* The RS/6000 prototype for stat doesn't include const, */
  221.     /* so we have to explicitly remove the const modifier. */
  222.     return (stat((char *)fname, pstat) < 0 ? gs_error_undefinedfilename : 0);
  223. }
  224.  
  225. private file_enum *
  226. os_enumerate(gx_io_device * iodev, const char *pat, uint patlen,
  227.          gs_memory_t * mem)
  228. {
  229.     return gp_enumerate_files_init(pat, patlen, mem);
  230. }
  231.  
  232. private int
  233. os_get_params(gx_io_device * iodev, gs_param_list * plist)
  234. {
  235.     int code;
  236.     int i0 = 0, i2 = 2;
  237.     bool btrue = true, bfalse = false;
  238.     int BlockSize;
  239.     long Free, LogicalSize;
  240.  
  241.     /*
  242.      * Return fake values for BlockSize and Free, since we can't get the
  243.      * correct values in a platform-independent manner.
  244.      */
  245.     BlockSize = 1024;
  246.     LogicalSize = 2000000000 / BlockSize;    /* about 2 Gb */
  247.     Free = LogicalSize * 3 / 4;            /* about 1.5 Gb */
  248.  
  249.     if (
  250.     (code = param_write_bool(plist, "HasNames", &btrue)) < 0 ||
  251.     (code = param_write_int(plist, "BlockSize", &BlockSize)) < 0 ||
  252.     (code = param_write_long(plist, "Free", &Free)) < 0 ||
  253.     (code = param_write_int(plist, "InitializeAction", &i0)) < 0 ||
  254.     (code = param_write_bool(plist, "Mounted", &btrue)) < 0 ||
  255.     (code = param_write_bool(plist, "Removable", &bfalse)) < 0 ||
  256.     (code = param_write_bool(plist, "Searchable", &btrue)) < 0 ||
  257.     (code = param_write_int(plist, "SearchOrder", &i2)) < 0 ||
  258.     (code = param_write_bool(plist, "Writeable", &btrue)) < 0 ||
  259.     (code = param_write_long(plist, "LogicalSize", &LogicalSize)) < 0
  260.     )
  261.     return code;
  262.     return 0;
  263. }
  264.  
  265. /* ------ Utilities ------ */
  266.  
  267. /* Get the N'th IODevice from the known device table. */
  268. gx_io_device *
  269. gs_getiodevice(int index)
  270. {
  271.     if (index < 0 || index >= gx_io_device_table_count)
  272.     return 0;        /* index out of range */
  273.     return io_device_table[index];
  274. }
  275.  
  276. /* Look up an IODevice name. */
  277. /* The name may be either %device or %device%. */
  278. gx_io_device *
  279. gs_findiodevice(const byte * str, uint len)
  280. {
  281.     int i;
  282.  
  283.     if (len > 1 && str[len - 1] == '%')
  284.     len--;
  285.     for (i = 0; i < gx_io_device_table_count; ++i) {
  286.     gx_io_device *iodev = io_device_table[i];
  287.     const char *dname = iodev->dname;
  288.  
  289.     if (dname && strlen(dname) == len + 1 && !memcmp(str, dname, len))
  290.         return iodev;
  291.     }
  292.     return 0;
  293. }
  294.  
  295. /* ------ Accessors ------ */
  296.  
  297. /* Get IODevice parameters. */
  298. int
  299. gs_getdevparams(gx_io_device * iodev, gs_param_list * plist)
  300. {                /* All IODevices have the Type parameter. */
  301.     gs_param_string ts;
  302.     int code;
  303.  
  304.     param_string_from_string(ts, iodev->dtype);
  305.     code = param_write_name(plist, "Type", &ts);
  306.     if (code < 0)
  307.     return code;
  308.     return (*iodev->procs.get_params) (iodev, plist);
  309. }
  310.  
  311. /* Put IODevice parameters. */
  312. int
  313. gs_putdevparams(gx_io_device * iodev, gs_param_list * plist)
  314. {
  315.     return (*iodev->procs.put_params) (iodev, plist);
  316. }
  317.  
  318. /* Convert an OS error number to a PostScript error */
  319. /* if opening a file fails. */
  320. int
  321. gs_fopen_errno_to_code(int eno)
  322. {                /* Different OSs vary widely in their error codes. */
  323.     /* We try to cover as many variations as we know about. */
  324.     switch (eno) {
  325. #ifdef ENOENT
  326.     case ENOENT:
  327.         return_error(gs_error_undefinedfilename);
  328. #endif
  329. #ifdef ENOFILE
  330. #  ifndef ENOENT
  331. #    define ENOENT ENOFILE
  332. #  endif
  333. #  if ENOFILE != ENOENT
  334.     case ENOFILE:
  335.         return_error(gs_error_undefinedfilename);
  336. #  endif
  337. #endif
  338. #ifdef ENAMETOOLONG
  339.     case ENAMETOOLONG:
  340.         return_error(gs_error_undefinedfilename);
  341. #endif
  342. #ifdef EACCES
  343.     case EACCES:
  344.         return_error(gs_error_invalidfileaccess);
  345. #endif
  346. #ifdef EMFILE
  347.     case EMFILE:
  348.         return_error(gs_error_limitcheck);
  349. #endif
  350. #ifdef ENFILE
  351.     case ENFILE:
  352.         return_error(gs_error_limitcheck);
  353. #endif
  354.     default:
  355.         return_error(gs_error_ioerror);
  356.     }
  357. }
  358.